﻿namespace clowncar
{
    using System;
    using System.IO;
    using System.Reflection;

    public static class AssemblyUtils
    {
        static string[] libNames;
        
        internal static string ExtractResource(string filename, string directory)
        {
            var targetFilename = DateTime.Now.ToString("yyyyMMddHHmmss") + "." +  filename;

            Assembly a = Assembly.GetExecutingAssembly();
            string filePath = null;
            string path = null;

            string shortName = new AssemblyName(filename).Name;
            string relevantName = AssemblyUtils.GetResourceName(shortName);
            if (relevantName == null)
            {
                throw new ArgumentException("No such resource -- " + filename);
            }

            using (Stream stream = a.GetManifestResourceStream(relevantName))
            {
                filePath = Path.Combine(directory, targetFilename);
                path = filePath;
                var fileInfoOutputFile = new FileInfo(filePath);

                using (FileStream streamToOutputFile = fileInfoOutputFile.OpenWrite())
                {
                    const int size = 4096;

                    byte[] bytes = new byte[size];
                    int numBytes;
                    while ((numBytes = stream.Read(bytes, 0, size)) > 0)
                    {
                        streamToOutputFile.Write(bytes, 0, numBytes);
                    }
                }
            }

            return filePath;
        }

        private static string GetResourceName(string shortName)
        {
            if (libNames == null)
            {
                libNames = Assembly.GetExecutingAssembly().GetManifestResourceNames();
            }

            string relevantName = null;

            foreach (string name in libNames)
            {
                if (name.Contains("." + shortName + ".dll") || name.EndsWith("." + shortName))
                {
                    relevantName = name;
                }
            }

            return relevantName;
        }
    }
}
